package gui;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

/**
 * Code taken straight from:
 * http://java-swing-tips.blogspot.com/2008/06/mouse-drag-auto-scrolling.html
 */
public class DragMoverListener
extends MouseInputAdapter implements ActionListener, HierarchyListener
{

    private static final int SPEED = 1;
    private final Cursor dc;
    private final Cursor hc = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
    private final Rectangle rect = new Rectangle();
    private final javax.swing.Timer scroller;
    private final JComponent label;
    private final JViewport vport;
    private Point startPt = new Point();
    private Point move  = new Point();

    public DragMoverListener(JViewport vport, JComponent comp)
    {
        this.vport = vport;
        this.label = comp;
        this.dc = label.getCursor();
        this.scroller = new javax.swing.Timer(5, this);
        vport.addMouseMotionListener(this);
        vport.addMouseListener(this);
        vport.addHierarchyListener(this);
    }
    
    public void hierarchyChanged(HierarchyEvent e)
    {
        if((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0
                && !vport.isDisplayable())
        {
            scroller.stop();
        }
    }
    
    public void actionPerformed(ActionEvent e)
    {
        Rectangle vr = vport.getViewRect();
        int w = vr.width;
        int h = vr.height;
        Point ptZero = SwingUtilities.convertPoint(vport,0,0,label);
        rect.setRect(ptZero.x-move.x, ptZero.y-move.y, w, h);
        label.scrollRectToVisible(rect);
    }
    
    public void mouseDragged(MouseEvent e)
    {
        scroller.stop();
        Point pt = e.getPoint();
        move.setLocation(SPEED*(pt.x-startPt.x), SPEED*(pt.y-startPt.y));
        startPt.setLocation(pt);
        scroller.start();
    }
    
    @Override
    public void mousePressed(MouseEvent e)
    {
        label.setCursor(hc);
        startPt.setLocation(e.getPoint());
        scroller.stop();
    }
    
    @Override
    public void mouseReleased(MouseEvent e)
    {
        label.setCursor(dc);
    }
    
    @Override
    public void mouseExited(MouseEvent e)
    {
        label.setCursor(dc);
        move.setLocation(0, 0);
        scroller.stop();
    }

}
